InsertKnot
1) The first test of the knot insertion algorithms is the case given in The NURBS Book's Figure 5.5-5.6.
The following test program reproduces these plots.
program test_curve_knot_insert
use splines
use points
implicit none
integer, parameter :: wp = selected_real_kind(15,307)
logical, parameter :: T = 1
logical, parameter :: F = 0
type(curve) :: curve1, curve2
type(cpt) :: cp(5)
real(wp) :: U(9)
cp(:)%x = [ 0.0_wp, 0.0_wp, 2.0_wp, 4.0_wp, 4.0_wp ]
cp(:)%y = [ 0.0_wp, 2.0_wp, 3.0_wp, 2.0_wp, 0.0_wp ]
!cp(:)%z = [ 0.0_wp, 0.0_wp, 1.0_wp, 0.0_wp, 0.0_wp ]
! knot vector
U = [0.0_wp,0.0_wp,0.0_wp,0.0_wp,2.0_wp,3.0_wp,3.0_wp,3.0_wp,3.0_wp]
curve1 = spl(dim=2, pd=1, p=[3], kXi=U, cp=cp)
curve2 = curve1
call curve2%InsertKnot(u=1.0_wp, r=3)
call plot( me=[curve1,curve2], &
plotCP=T, labelCP=T,&
terminal="png", &
fname="test_F5.5", &
title="Knot insertion into a cubic curve three times") !
call curve1%N(1)%plot( fname="test_F5.6a", &
terminal="png", &
title="Basis functions before knot insertion")
call curve2%N(1)%plot( fname="test_F5.6b", &
terminal="png", &
title="Basis functions after knot insertion")
end program test_curve_knot_insert
Inserting internal knots so that their multiplicity equals to polynomial degree splits curve. In this example, the curve is divided by . The resulting plots are as follow,
2) The second test is the case illustrated in figures from 5.9 to 5.14.
The following test program reproduces these plots.
program test_surface_knot_insert
use splines
use points
implicit none
integer, parameter :: wp = selected_real_kind(15,307)
logical, parameter :: T = .true.
logical, parameter :: F = .false.
type(surface) :: surf
type(cpt) :: scp(16)
real(wp) :: U(8), V(7)
scp(:)%x = [ 1.0, 1.0, 1.0, 1.0, 0.2, 0.2, 0.2, 0.2, &
-0.2, -0.2, -0.2, -0.2, -1.0, -1.0, -1.0, -1.0]
scp(:)%y = [-1.0, -0.2, 0.2, 1.0, -1.0, -0.2, 0.2, 1.0, &
-1.0, -0.2, 0.2, 1.0, -1.0, -0.2, 0.2, 1.0]
scp(:)%z = [ 1.0, 1.0, -2.0, -2.0, 1.0, 1.0, -2.0, -2.0, &
3.0, 3.0, 1.0, 1.0, 3.0, 3.0, 1.0, 1.0]
U = [0.0_wp,0.0_wp,0.0_wp,0.0_wp,1.0_wp,1.0_wp,1.0_wp,1.0_wp]
V = [0.0_wp,0.0_wp,0.0_wp,0.50_wp,1.0_wp,1.0_wp,1.0_wp]
surf = spl(dim=3, pd=2, p=[3,2], kXi=U, kEta=V, cp=scp)
! Plot the initial surface
call surf%plot( plotCP = T, labelCP = T, &
terminal = 'png', &
ls = "lw 1 lc rgb 'dark-grey'", &
fname = "test_F5.11", &
plotOpt = ["set view ,120"], & !set the view as in the book.
title = "A (cubic x quadratic) surface" )
! Splitting the surface in the v-direction at u=0.4
call surf%InsertKnot(u=0.4_wp,r=3)
call surf%plot( plotCP = T, labelCP = T, &
terminal = 'png', &
fname = "test_F5.12", &
ls = "lw 1 lc rgb 'dark-grey'", &
plotOpt = ["set view ,120"], &
title = "Splitting the surface in the v-direction at u = 0.4" )
! Splitting the surface in the u-direction at v=0.7
call surf%InsertKnot(v=0.7_wp,r=2)
call surf%plot( plotCP = T, labelCP = T, &
terminal = 'png', &
fname ="test_F5.14", &
ls = "lw 1 lc rgb 'dark-grey'", &
plotOpt =["set view ,120"], &
title="Splitting the surface in the u-direction at v = 0.7" )
end program test_surface_knot_insert
The results are given in the following figures. In the second plot, the isocurve defined by control points splits the surface. In the third one, two isocurves defined by control points and divide the surface into four pieces.